package com.dmcb.trade.business.crawlers.author;

import com.dmcb.common.business.services.BaseService;
import com.dmcb.common.business.utils.DateUtil;
import com.dmcb.common.web.conversion.JsonResult;
import com.dmcb.common.business.utils.WebClientUtil;
import com.dmcb.trade.business.constants.TradeConstant;
import com.dmcb.trade.business.entities.Article;
import com.dmcb.trade.business.entities.MonitorWechat;
import com.dmcb.trade.business.mappers.ArticleMonitorMapper;
import com.dmcb.trade.controller.ArticleCrawlerController;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * 钱江晚报电子文章导入
 * Created by 黑米 on 2016/10/31.
 */
@Service
public class QianJiangCrawler extends BaseService {

    @Autowired
    private WebClientUtil webClientUtil;
    @Autowired
    private ArticleCrawlerController articleCrawlerController;
    @Autowired
    private ArticleMonitorMapper articleMonitorMapper;

    Logger logger = LoggerFactory.getLogger(QianJiangCrawler.class);

    /**
     * @param time 需要导入电子报的文章日期
     * @return 成功导入文章数量
     */
    public JsonResult qianJiang(String time, Integer type) throws Exception {
        Elements elementss; //保存报纸类别
        Elements elements; // 保存文章列表页
        type = type == null ? 0 : type;
        Map<String, String> map = getData(type);
        //获取当日时间，组合查询消息
        // http://qjwb.zjol.com.cn/html/2016-10/31/node_85.htm;
        int i = 0;
        int sum = 0;
        try {
            time = DateUtil.getTimeByDianZiBao(time);
            int weChatId = Integer.parseInt(map.get("weChatId"));
            String domain = map.get("domain");
            String headPage = map.get("headPage");
            //node_77为要闻（标题简介之类的），根据该页面获取页面列表
            String link1 = domain + time + headPage;
            logger.info("导入起始链接：" + link1 + ";map=" + map.toString() + ";type :" + type + "time:" + time);
            HtmlPage htmlPage = webClientUtil.getPage(link1);
            Document doc = Jsoup.parse(htmlPage.asXml());
            if (doc == null) {
                return null;
            }
            if (type == 10 || type == 5 || type == 6) {
                elementss = doc.select("tr[valign=top]>td>table>tbody>tr>td.default");
            } else if (type == 2) {
                elementss = doc.select("div.liebiao>ul>li");
            } else {
                elementss = doc.select("div.main-ednav-nav>dl");
            }
            if (elementss == null || elementss.size() == 0) {
                logger.info("没有获取到该期报纸内容：" + link1);
                return null;
            }
            for (Element e : elementss) {
                String page = e.select("a").attr("href");
                if (type == 2) {
                    page = e.select("a").last().attr("href");
                }
                if (StringUtils.isBlank(page)) {
                    continue;
                }
                String link = domain + time + "/" + page;
                htmlPage = webClientUtil.getPage(link);
                doc = Jsoup.parse(htmlPage.asXml());
                if (doc == null) {
                    return error("解析失败");
                }
                if (type == 10 || type == 5 || type == 6) {
                    elements = doc.select("td[align=left]>table>tbody>tr>td.default");
                } else if (type == 2) {
                    elements = doc.select("div.m_m>map>area");
                } else if (type == 4) {
                    elements = doc.select("div.main-ed-map>map>area");
                } else {
                    elements = doc.select("ul.main-ed-articlenav-list>li");
                }
                if (elements == null || elements.size() == 0) {
                    continue;
                }
                for (Element element : elements) {
                    sum++;
                    //content_3200560.htm?div=-1
                    String src;
                    if (type == 2 || type == 4) {
                        src = element.attr("href");
                    } else {
                        src = element.select("a").first().attr("href");
                    }
                    src = domain + time + "/" + src;
                    //此处版权方ID写死，以后有更好的办法再改
                    JsonResult js = articleCrawlerController.crawlMonitor(weChatId, src);
                    if (js.getStatus() == JsonResult.STATUS_ERROR) {
                        logger.info("该文章链接已另外解析，请核实是否正确：" + src);
                        //没有获取文章内容们需要用另一种方式解析
                        js = crawl(src, weChatId, type);
                    }
                    if (js.getStatus() == JsonResult.STATUS_SUCCESS) {
                        i++;
                    }
                    if (i != sum) {
                        logger.info("该篇文章导入失败，核实是系统问题还是，标题重复：" + src);
                        sum--;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("出现错误", e);
            return error(e.getMessage());
        }
        logger.info("实际导入：" + i + "篇，如有出入，请核实是否有重复");
        return success(i);
    }

    /**
     * @param src    文章链接
     * @param userId 用户ID
     */
    public JsonResult crawl(String src, int userId, int type) throws Exception {
        HtmlPage htmlPage = webClientUtil.getPage(src);
        if (htmlPage == null) {
            return error("解析失败");
        }
        Document doc = Jsoup.parse(htmlPage.asXml());
        MonitorWechat monitorWechat = articleMonitorMapper.queryByUserId(userId);
        Element eTitle;
        String title = "";
        String content = "";
        if (type == 2) {
            eTitle = doc.select("h1").first();
            if (eTitle == null) {
                return error("标题获取失败");
            }
            title = eTitle.text();
            content = doc.select("div.content").text();
        } else if (type == 4) {
            eTitle = doc.select("div.main-article-con>founder-content>p").first();
            if (eTitle == null) {
                return error("标题获取失败");
            }
            title = eTitle.text();
            title = title.length() > 99 ? title.substring(0, 99) : title;
            content = doc.select("div#ozoom").text();
            if (content.length() > 300) {
                logger.info("文章内容少于300字，自动忽略:" + src);
                return error("文章内容少于300字，自动忽略");
            }
        } else {
            title = doc.select("h1.main-article-title").text();
            content = doc.select("div.main_ar_pic_text").text();
        }
        if (StringUtils.isBlank(title)) {
            logger.info("该文章没有获取到标题：" + src);
            return error("该文章没有获取到标题：" + src);
        }
        // 校验该作者标题是否存在
        Article article = articleMonitorMapper.queryByUserTitle(monitorWechat.getId(), title);
        if (article == null) {
            // 新文章
            article = new Article();
            article.setAuthorId(monitorWechat.getId());
            article.setTitle(title);
            article.setLink(src);
        }
        // 如果已经存在，直接返回
        if (article.getId() > 0) {
            logger.info(TradeConstant.MSG_ERROR_TITLE_EXIST);
            return error("已存在");
        }
        article.setBody(content);
        articleMonitorMapper.insertMonitorArticle(article);
        return success();
    }

    public JsonResult saveAll(String time) throws Exception {
        int[] types = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int type : types) {
            qianJiang(time, type);
            logger.info("type ：" + type + "执行完毕！");
        }
        return success("全部导入完毕");
    }


    public Map<String, String> getData(int type) {
        Map<String, String> map = new HashMap<String, String>();
        LinkedHashMap<Integer, String[]> linkedHashMap = new LinkedHashMap<Integer, String[]>();
        //网站域名、微信检测用户ID、起始页
        linkedHashMap.put(0, new String[]{"http://qjwbepaper.qjwb.com.cn/html/", "2268", "/node_77.htm"});
        linkedHashMap.put(1, new String[]{"http://zjrb.zjol.com.cn/html/", "2866", "/node_18.htm"});
        linkedHashMap.put(2, new String[]{"http://gcdy.zjol.com.cn/html/", "2867", "/node_2.htm"});
        linkedHashMap.put(3, new String[]{"http://zjfzb.zjol.com.cn/html/", "2868", "/node_2657.htm"});
        linkedHashMap.put(4, new String[]{"http://jnyb.zjol.com.cn/html/", "2871", "/node_2617.htm"});
        linkedHashMap.put(5, new String[]{"http://hnrb.zjol.com.cn/hnrb/html/", "2874", "/node_2.htm"});
        linkedHashMap.put(6, new String[]{"http://dyrb.zjol.com.cn/html/", "2876", "/node_2.htm"});
        linkedHashMap.put(7, new String[]{"http://wldaily.zjol.com.cn/html/", "2878", "/node_2277.htm"});
        linkedHashMap.put(8, new String[]{"http://msb.zjol.com.cn/html/", "2879", "/node_199.htm"});
        linkedHashMap.put(9, new String[]{"http://zjlnb.zjol.com.cn/html/", "2880", "/node_36.htm"});
        linkedHashMap.put(10, new String[]{"http://epaper.zgkqw.com/html/", "2875", "/node_2.htm"});
        String[] data = linkedHashMap.get(type);
        map.put("domain", data[0]);
        map.put("weChatId", data[1]);
        map.put("headPage", data[2]);
        return map;
    }


}
